The effect component framework is provided for you to simplify the development of QuickTime video effects components.
The QuickTime 3 SDK includes the folder DimmerEffect , which contains the framework, complete with associated resources and makefiles. See the ReadMe file in the DimmerEffect folder for full installation and use instructions.
To adapt the dimmer framework to create your own component, search through the source code file Effect.c for the comments " *** CHANGE *** ". These comments mark the sections of the source code you will need to change to write your own effect.
The following sections take you through the specific changes you need to make to the framework. All the changes except the last, which implements the actual effect algorithm, are made to the Effect.c file.
The first change you may need to make is to the following #define :
#define kMaxAsyncFrames 0
This value defines the number of frames that can be queued for asynchronous rendering by this effect. If your effect declares that is can handle more than 0 asynchronous frames, frames may be queued for rendering. If you wish to render synchronously, set kMaxAsyncFrames to 0 , otherwise, set it to the number of frames that can be held in the queue.
Most effects require one or more sources to operate on, though some effects--such as Apple's fire effect--operate without any sources. The dimmer effect uses two sources: the first is the source to fade to black, the second is the source to fade up on. Most effects transition between two sources. Sometimes, effects control the transition between two scenes by blending in one or more other sources, in which case the effect may require three or more sources. You may also want to implement a filter effect that has only a single source and produces a transformed version of that source.
You set the value of kMaxSources to the maximum number of sources required by the effect. Effects that can take more than one source should be prepared to handle the case when fewer than the maximum number of sources are actually provided. For example, if your effect expects two sources to transition between and a third source to use as a mask, your code must handle the case where only the two transition sources are provided. In this case you should use a default mask instead of a third source.
The framework defines two global data structures: BlitGlobals and EffectGlobals . The BlitGlobals structure holds information related to drawing a single frame of the effect, while the EffectGlobals holds data for the entire effect as it is executed. These data structures are global to an instance of the effect component. That is, if you have multiple instances of the component opened, each instance gets its own copy of both data structures.
You can add fields to the BlitGlobals data structure to hold information specific to your effect. A set of standard fields are already defined, which hold information used by the framework. You can add your own effect-specific fields between the *** CHANGE *** and *** END CHANGE *** comments.
The example defines two fields, dimValue and direction . These hold the current dim value for the effect and a flag indicating whether it is fading down or up, respectively. Because the dimmer fades the first scene down to black then fades up on the second scene, it also needs to store the dim value between individual frames. This value is stored in the dimValue field of BlitGlobals .
You can also add fields to the EffectGlobals structure. Generally, you will read the values for the parameters to your effect in these fields so that they can be referenced while the effect executes.
The internal function BlitterPreflight is called from EffectSetup before the first frame of the effect is rendered. This function's main task is to validate the bit depth that the effect is being requested to support.
The bit depth that the effect is being asked to operate at is passed in the depth parameter to BlitterPreflight . The function should return in the same parameter the bit depth at which it wants to operate.
For example, the dimmer effect can operate on 16-bit or 32-bit sources. If either of these values is passed in, it simply returns depth unaltered. If any other bit depth is requested, it sets depth to 16 , the default bit depth for this effect.
Your effect should validate the bit depth passed in a similar way. Apple recommends that your effect support at least 16- and 32-bit depths.
When you set the depth parameter to a different value than it was on entry to BlitterPreflight , QuickTime creates an offscreen buffer for the sources and destination of the effect. All data is passed through these offscreen buffers, to ensure that your effect only sees data in a format it can handle.
The BlitterSetDest function is called from EffectBegin and is passed the effect's destination, in the form of a PixMap . The BlitterSetDest function should calculate the base address and rowBytes values for the destination and store these in the BlitGlobals data structure for future reference.
You need to make changes to this function only if your effect supports destinations in bit depths other than 16-bit and 32-bit.
This function calls the functions that implement your effect algorithm. The function names to be called are those generated by the blit macros.
The example code supports the three most common pixel formats in 16-bit and 32-bit. If your effect needs to support other bit depths or pixel formats, you need to update the switch statement in this function so that the appropriate drawing functions are called.
This function is called when the client software has finished using your component. At this time, your component should dispose of any memory it allocated. In particular, you should call DisposeTweenRecord for each tween record you allocated and then call DisposeTweenGlobals .
The parameters of the effect are read in the EffectsFrameEffectBegin function. Your effect should read its parameter values in the section between the *** CHANGE *** and *** END CHANGE *** comments, reading either non-tweened or (more frequently) tweened values. Example code for both these cases is given in "Reading Parameter Values" .
Once you have read in the parameter values, you need to tween those parameters that contain tween records. This code should be placed between the second pair of *** CHANGE *** and *** END CHANGE *** comments. Again, example code to do this is supplied, see "Tweening Parameter Values" .
The last stage in adapting the framework is to implement your effect algorithm. You need to provide one implementation per bit depth that your effect explicitly supports, and each implementation must be placed in a separate file. These files are named EffectFilter16.c , EffectFilter32.c , and so forth.
The dimmer effect code provides an example of the pixel manipulations that an effect will typically perform, and shows how to use the blit macros to support multiple pixel formats at a given bit depth.
Clearly, the details of these routines are entirely dependent on the effect being implemented.
| Previous | Chapter Contents | Chapter Top | Next |